package com.yusvn.scm.common;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.poi.excel.ExcelReader;
import com.github.yitter.idgen.YitIdHelper;
import com.jfinal.aop.Inject;
import com.jfinal.core.Controller;
import com.jfinal.core.NotAction;
import com.jfinal.ext.cors.EnableCORS;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.upload.UploadFile;
import com.yusvn.scm.admin.service.LoginService;
import com.yusvn.scm.common.constant.Const;
import com.yusvn.scm.common.kit.MyKit;
import com.yusvn.scm.common.kit.RetKit;
import com.yusvn.scm.common.model.SysUser;

import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.StyleSet;

/**
 * Controller基类
 * @author liugz
 *
 */
@EnableCORS
public class BaseController extends Controller {

	@Inject
	LoginService loginSrv;
	
	/**
	 * 获取请求头中的sessionId
	 */
	@NotAction
	public String getSessionId() {
		String access_token = getPara(Const.TOKEN_HEADER_NAME);  //Authorization
		
		if (access_token == null || access_token.trim().isEmpty()) {
            access_token = getHeader(Const.TOKEN_HEADER_NAME);
        }
        return access_token;
	}
	
	/**
	 * 获取当前登录的user 
	 * 根据sessionId获取登录用户信息
	 */
	@NotAction
	public SysUser getLoginUser() {
		return loginSrv.loginWithSessionId(getSessionId(), getRequest());
	}

    /**
     * 获取当前登录的userId
     */
	@NotAction
    public Integer getLoginUserId() {
    	SysUser loginUser = getLoginUser();
        return loginUser == null ? null : loginUser.getUserId();
    }

	/**
	 * 获取当前登录用户对应的ERP用户编号
	 */
	@NotAction
	public String getLoginErpUsercode() {
		SysUser loginUser = getLoginUser();
		return loginUser == null ? null : loginUser.getPhone();
	}
	
    /**
     * 获取当前登录用户的原ERP中所属仓店（暂用email字段代替）
     */
	@NotAction
    public String getLoginUserSscd() {
    	SysUser loginUser = getLoginUser();
        return loginUser == null ? null : loginUser.getEmail();
    }
    
    /**
     * 获取请求参数。<br>
     * 覆盖Controller中的getKv()方法，方便sql模板多条件多值查询。<br>
     * 默认分割字符为英文逗号。<br>
     */
	@NotAction
	public Kv getKv() {
		return getKv(",");
	}
	
    /**
     * 获取请求参数。<br>
     * 覆盖Controller中的getKv()方法，方便sql模板多条件多值查询。<br>
     * 可以手动串分割字符，默认分割字符为英文逗号。
     */
	@SuppressWarnings("unchecked")
	@NotAction
	public Kv getKv(String splitStr) {
		splitStr = StrKit.isBlank(splitStr) ? "," : splitStr; //默认分割标识字符为英文逗号,
		Kv kv = new Kv();
		Map<String, String[]> paraMap = getRequest().getParameterMap();
		
		for (Entry<String, String[]> entry : paraMap.entrySet()) {
			String[] values = entry.getValue();
			
			//如果请求的某个参数只有一个值，则根据标识字符先分割为数组
			if(values.length==1) {
				values = values[0].split(splitStr);
			}
			
			//System.out.println(entry.getKey()+" 参数values:"+values);
			
			/*
			 * 上面处理完成，如果数组的值只1个，则直接放字符值；
			 * 如果数组的值大于1，则存数组，供sql模板循环遍历；
			 * 否则存入null值。
			 */
			if(values.length==1) {
				String value = (values != null && values.length > 0) ? values[0] : null;
				// 排除值不为空,或空数组空对象
				if(StrKit.notNull(value) && !"[]".equals(value) && !"{}".equals(value) && !"".equals(value) ) { 
					kv.put(entry.getKey(), value);
				}
				//kv.put(entry.getKey(), "".equals(value) ? null : value);
			}else if(values.length>1) {
				kv.put(entry.getKey(), values);
			}else {
				//kv.put(entry.getKey(), null);
			}
		}
		return kv;
	}

	/**
	 * 获取请求参数。<br>
	 * getRawData()获取的json字符串，转换为Kv<br>
	 * @param jsonStr
	 * @return
	 */
	@NotAction
	public Kv jsonStrToKv(String jsonStr) {
		return MyKit.jsonStrToKv(jsonStr);
	}
	
	
	/**
	 * 获取数组变量
	 */
	@NotAction
	public List<String> getArray(String arrayName) {		
		List<String> ids = new ArrayList<>();
		for (int i = 0; i < 100; i++) {
			if (getPara(arrayName + "[" + i + "]")== null) {
				break;
			} 
			ids.add(getPara(arrayName + "[" + i + "]"));
		}
		return ids;
	}
	

	/**
	 * 通用导出Excel方法 适用于前后分离的项目 如VUE
	 * 
	 * @param recList 需导出的数据
	 * @param fileNmae 导出文件名
	 * @param headerAlias 导出列的别名
	 */
	public void exportExcel(List<Record> recList, String fileNmae, String[][] headerAlias) {
		List<Map<String,Object>> mapList = new LinkedList<>();
		recList.forEach(record -> mapList.add(record.getColumns()));

		//通过工具类创建writer
		//ExcelWriter writer = ExcelUtil.getWriter(fileName);
		BigExcelWriter writer= ExcelUtil.getBigWriter(fileNmae); //大量数据输出
		
		try {
			//自定义标题别名
			for(int i=0;i<headerAlias.length; i++) {
				writer.addHeaderAlias(headerAlias[i][0], headerAlias[i][1]);
			}
			//自定义表格样式
			StyleSet style = writer.getStyleSet();
			style.getCellStyleForNumber().setDataFormat((short) 0); //数字默认小数点后不要加0
			
			
			//writer.setColumnWidth(0,20).setColumnWidth(1,20).setColumnWidth(2,30).setColumnWidth(3,20).setColumnWidth(4,20);
			//一次性写出内容，强制输出标题
			writer.write(mapList, true);
			
			HttpServletResponse response = getResponse();
	        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
	        response.setCharacterEncoding("UTF-8");
	        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
	        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(fileNmae,"utf-8") );
	        ServletOutputStream out;
			out = response.getOutputStream();
			writer.flush(out, true);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
            if(writer!=null){
                writer.close(); //关闭writer，释放内存
            }
        }
        
	}

	//导入配置补货
	public RetKit importExcel(UploadFile file, String tableName, String mid){
		//读取表格中第一个sheet的内容
		ExcelReader reader = ExcelUtil.getReader(file.getFile(), 0); //0标识第一个sheet
		List<List<Object>> readAll = reader.read();

		if (readAll.size() < 0){
			return RetKit.fail("导入的模板数据为空");
		}
		//获取excel的第一行
		List<Object> objects = readAll.get(0);
		String tableRow = "(";
		// 拼接需要新增的字段
		for (int i = 0; i<objects.size();i++){
			if (i == 0){
				tableRow += "id,";
				if (mid != null){
					tableRow += "mid,";
				}
			}
			if (i == objects.size()-1){
				tableRow+=objects.get(i)+")";
			}else {
				tableRow+=objects.get(i)+",";
			}
		}
		// 获取去头的数据体
		List<List<Object>> recordList = readAll.subList(2, readAll.size());
		//拼接好需要新增的值
		List<String> splicinCompleted = new ArrayList<>();
		for(int i = 0; i<recordList.size(); i++){
			String recordRow = "(";
			for (int k = 0; k<recordList.get(i).size();k++){
				//拼接新增的值
				if (k == 0){
					recordRow += YitIdHelper.nextId()+","; // 自动计算id
					if (mid != null){
						recordRow += mid+",";
					}
				}
				if (k == recordList.get(i).size()-1){
					recordRow+="'"+recordList.get(i).get(k)+"')";
				}else {
					recordRow+="'"+recordList.get(i).get(k)+"',";
				}
			}
			splicinCompleted.add(recordRow);
		}
		List<String> sqlList = new ArrayList<>();
		for (String s : splicinCompleted) {
			sqlList.add("insert into "+tableName+tableRow+" values"+s);
		}
		//调用批量新增方法
		int[] batch = Db.use(Const.SCMDB).batch(sqlList, sqlList.size());

		// 统计新增成功的条数
		int cntOk = 0;
		for(int i=0; i<batch.length; i++) {
			if(batch[i]==-2 || batch[i]==1) { //oracle返回-2、sqlserver返回1，表示成功
				cntOk++;
			}
		}

		return RetKit.ok("导入"+cntOk+"行数据");
	}
	
}
